package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.controller.StockAsnController;
import com.itheima.dto.WarehousingEntryDTO;
import com.itheima.dto.WarehousingEntryDetailsDTO;
import com.itheima.mapper.WarehousingEntryDetailsMapper;
import com.itheima.mapper.WarehousingEntryDetailsSortMapper;
import com.itheima.mapper.WarehousingEntryMapper;
import com.itheima.mapper.WarehousingEntryUpMapper;
import com.itheima.pojo.WarehousingEntry;
import com.itheima.pojo.WarehousingEntryDetails;
import com.itheima.pojo.WarehousingEntryDetailsSort;
import com.itheima.pojo.WarehousingEntryUp;
import com.itheima.service.WarehousingEntryService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class WarehousingEntryServiceImpl extends ServiceImpl<WarehousingEntryMapper, WarehousingEntry> implements WarehousingEntryService {

    @Autowired
    private WarehousingEntryDetailsMapper warehousingEntryDetailsMapper;
    @Autowired
    private WarehousingEntryDetailsSortMapper warehousingEntryDetailsSortMapper;

    @Autowired
    private WarehousingEntryUpMapper warehousingEntryUpMapper;

    @Override
    @Transactional
    public void addArrivalNotification(WarehousingEntryDTO warehousingEntryDTO) {
        // 创建入库单主表记录
        WarehousingEntry warehousingEntry = new WarehousingEntry();
        BeanUtils.copyProperties(warehousingEntryDTO, warehousingEntry);
        // 转换字段名
        warehousingEntry.setConsignorId(warehousingEntryDTO.getOwnerId());
        warehousingEntry.setBatchNumber(warehousingEntryDTO.getBatch());
        warehousingEntry.setPredictedArrivalTime(warehousingEntryDTO.getExpectedArrivalTime());
        // 设置默认值
        warehousingEntry.setStatus(1); // 未确认状态
        warehousingEntry.setCreateTime(LocalDateTime.now());
        warehousingEntry.setIsDel(1); // 未删除

        // 保存入库单主表
        this.save(warehousingEntry);

        // 保存明细表记录
        if (warehousingEntryDTO.getItems() != null && !warehousingEntryDTO.getItems().isEmpty()) {
            List<WarehousingEntryDetails> detailsList = warehousingEntryDTO.getItems().stream().map(item -> {
                WarehousingEntryDetails detail = new WarehousingEntryDetails();
                // 这里需要根据skuCode查询skuId，根据supplierName查询supplierId
                // 由于缺少相关service，暂时使用默认值
                detail.setSkuId(1L); // 需要根据skuCode查询得到
                detail.setSupplierId(1L); // 需要根据supplierName查询得到
                detail.setPrice(item.getPrice() != null ? item.getPrice().intValue() : 0);
                detail.setCount(0); // 数量需要根据实际业务确定
                detail.setWarehousingEntryId(warehousingEntry.getId());
                detail.setPredictedArrivalTime(warehousingEntryDTO.getExpectedArrivalTime());
                detail.setStatus(1); // 未到货状态
                detail.setCreateTime(LocalDateTime.now());
                detail.setIsDel(1); // 未删除
                return detail;
            }).collect(Collectors.toList());

            warehousingEntryDetailsMapper.insertBatchSomeColumn(detailsList);
        }
    }

    @Override
    @Transactional
    public void updateArrivalNotification(WarehousingEntryDTO warehousingEntryDTO) {
        // 更新入库单主表记录
        WarehousingEntry warehousingEntry = new WarehousingEntry();
        BeanUtils.copyProperties(warehousingEntryDTO, warehousingEntry);
        // 转换字段名
        warehousingEntry.setConsignorId(warehousingEntryDTO.getOwnerId());
        warehousingEntry.setBatchNumber(warehousingEntryDTO.getBatch());
        warehousingEntry.setPredictedArrivalTime(warehousingEntryDTO.getExpectedArrivalTime());
        warehousingEntry.setUpdateTime(LocalDateTime.now());

        // 更新入库单主表
        this.updateById(warehousingEntry);

        // 删除原有的明细记录
        warehousingEntryDetailsMapper.delete(new LambdaQueryWrapper<WarehousingEntryDetails>()
                .eq(WarehousingEntryDetails::getWarehousingEntryId, warehousingEntryDTO.getId()));

        // 重新插入明细表记录
        if (warehousingEntryDTO.getItems() != null && !warehousingEntryDTO.getItems().isEmpty()) {
            List<WarehousingEntryDetails> detailsList = warehousingEntryDTO.getItems().stream().map(item -> {
                WarehousingEntryDetails detail = new WarehousingEntryDetails();
                detail.setId(item.getId()); // 如果有ID则更新，否则新增
                // 这里需要根据skuCode查询skuId，根据supplierName查询supplierId
                // 由于缺少相关service，暂时使用默认值
                detail.setSkuId(1L); // 需要根据skuCode查询得到
                detail.setSupplierId(1L); // 需要根据supplierName查询得到
                detail.setPrice(item.getPrice() != null ? item.getPrice().intValue() : 0);
                detail.setCount(0); // 数量需要根据实际业务确定
                detail.setWarehousingEntryId(warehousingEntry.getId());
                detail.setPredictedArrivalTime(warehousingEntryDTO.getExpectedArrivalTime());
                detail.setStatus(1); // 未到货状态
                detail.setCreateTime(LocalDateTime.now());
                detail.setIsDel(1); // 未删除
                return detail;
            }).collect(Collectors.toList());

            warehousingEntryDetailsMapper.insertBatchSomeColumn(detailsList);
        }
    }

    @Override
    @Transactional
    public void deleteArrivalNotification(Long id) {
        // 逻辑删除入库单主表记录
        WarehousingEntry warehousingEntry = new WarehousingEntry();
        warehousingEntry.setId(id);
        warehousingEntry.setIsDel(2); // 已删除
        warehousingEntry.setUpdateTime(LocalDateTime.now());
        this.updateById(warehousingEntry);

        // 逻辑删除明细表记录
        WarehousingEntryDetails detail = new WarehousingEntryDetails();
        detail.setIsDel(2); // 已删除
        warehousingEntryDetailsMapper.update(detail,
                new LambdaQueryWrapper<WarehousingEntryDetails>()
                        .eq(WarehousingEntryDetails::getWarehousingEntryId, id));
    }

    @Override
    @Transactional
    public void confirmArrival(List<Long> ids, LocalDate arrivalTime) {
        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("请选择要确认到货的记录");
        }

        if (arrivalTime == null) {
            throw new RuntimeException("请填写到达时间");
        }

        // 更新明细记录状态为已到货(状态2)
        List<WarehousingEntryDetails> detailsToUpdate = new ArrayList<>();
        for (Long id : ids) {
            WarehousingEntryDetails detail = new WarehousingEntryDetails();
            detail.setId(id);
            detail.setStatus(2); // 已到货
            detail.setRealArrivalTime(LocalDate.from(arrivalTime));
            detail.setUpdateTime(LocalDateTime.now());
            detailsToUpdate.add(detail);
        }

        // 批量更新明细记录
        for (WarehousingEntryDetails detail : detailsToUpdate) {
            warehousingEntryDetailsMapper.updateById(detail);
        }

        // 更新主表状态
        // 查找涉及的入库单ID
        List<WarehousingEntryDetails> details = warehousingEntryDetailsMapper.selectBatchIds(ids);
        Set<Long> entryIds = details.stream()
                .map(WarehousingEntryDetails::getWarehousingEntryId)
                .collect(Collectors.toSet());

        // 更新主表状态
        for (Long entryId : entryIds) {
            // 查询该入库单下所有明细的状态
            LambdaQueryWrapper<WarehousingEntryDetails> detailQuery = new LambdaQueryWrapper<>();
            detailQuery.eq(WarehousingEntryDetails::getWarehousingEntryId, entryId);
            List<WarehousingEntryDetails> allDetails = warehousingEntryDetailsMapper.selectList(detailQuery);

            // 判断是否全部确认到货
            boolean allArrived = allDetails.stream()
                    .allMatch(d -> d.getStatus() == 2);

            // 判断是否部分确认到货
            boolean hasArrived = allDetails.stream()
                    .anyMatch(d -> d.getStatus() == 2);

            // 更新主表状态
            WarehousingEntry entry = new WarehousingEntry();
            entry.setId(entryId);
            entry.setUpdateTime(LocalDateTime.now());

            if (allArrived) {
                entry.setStatus(3); // 全部确认
            } else if (hasArrived) {
                entry.setStatus(2); // 部分确认
            }

            this.updateById(entry);
        }
    }

    @Override
    @Transactional
    public void confirmUnloaded(List<Long> ids, Integer unloadStaffId, LocalDateTime unloadTime) {
        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("请选择要确认卸货的记录");
        }

        if (unloadStaffId == null) {
            throw new RuntimeException("请选择卸货员工");
        }

        if (unloadTime == null) {
            throw new RuntimeException("请填写卸货时间");
        }

        // 更新明细记录状态为已卸货(状态3)
        List<WarehousingEntryDetails> detailsToUpdate = new ArrayList<>();
        for (Long id : ids) {
            WarehousingEntryDetails detail = new WarehousingEntryDetails();
            detail.setId(id);
            detail.setStatus(3); // 已卸货
            detail.setUnloadEmpId(unloadStaffId);
            detail.setUnloadTime(unloadTime);
            detail.setUpdateTime(LocalDateTime.now());
            detailsToUpdate.add(detail);
        }

        // 批量更新明细记录
        for (WarehousingEntryDetails detail : detailsToUpdate) {
            warehousingEntryDetailsMapper.updateById(detail);
        }
    }

    @Override
    @Transactional
    public void revertUnloaded(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("请选择要撤销卸货状态的记录");
        }

        // 更新明细记录状态为未到货(状态1)
        List<WarehousingEntryDetails> detailsToUpdate = new ArrayList<>();
        for (Long id : ids) {
            WarehousingEntryDetails detail = new WarehousingEntryDetails();
            detail.setId(id);
            detail.setStatus(1); // 未到货
            detail.setUnloadEmpId(null);
            detail.setUnloadTime(null);
            detail.setUpdateTime(LocalDateTime.now());
            detailsToUpdate.add(detail);
        }

        // 批量更新明细记录
        for (WarehousingEntryDetails detail : detailsToUpdate) {
            warehousingEntryDetailsMapper.updateById(detail);
        }
    }

    @Override
    @Transactional
    public void performSorting(Long id, Integer sortQuantity, LocalDateTime expireDate) {
        if (id == null) {
            throw new RuntimeException("请选择要分拣的记录");
        }

        if (sortQuantity == null || sortQuantity <= 0) {
            throw new RuntimeException("请输入正确的分拣数量");
        }

        if (expireDate == null) {
            throw new RuntimeException("请选择过期时间");
        }

        // 查询明细记录
        WarehousingEntryDetails detail = warehousingEntryDetailsMapper.selectById(id);
        if (detail == null) {
            throw new RuntimeException("未找到对应的入库明细记录");
        }

        // 检查状态是否为已卸货(状态3)
        if (detail.getStatus() != 3) {
            throw new RuntimeException("只有已卸货的记录才能进行分拣操作");
        }

        // 创建分拣记录
        WarehousingEntryDetailsSort sortRecord = new WarehousingEntryDetailsSort();
        sortRecord.setCount(sortQuantity);
        sortRecord.setWarehousingEntryDetailsId(id);
        sortRecord.setSkuId(detail.getSkuId());
        sortRecord.setStatus(1); // 分拣中
        sortRecord.setCreateTime(LocalDateTime.now());
        sortRecord.setIsDel(1); // 未删除

        // 保存分拣记录
        warehousingEntryDetailsSortMapper.insert(sortRecord);
    }

    @Override
    @Transactional
    public void confirmSortingCompleted(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("请选择要确认分拣完成的记录");
        }

        // 更新分拣记录状态为已完成分拣(状态2)
        for (Long id : ids) {
            WarehousingEntryDetailsSort sortRecord = new WarehousingEntryDetailsSort();
            sortRecord.setId(id);
            sortRecord.setStatus(2); // 已完成分拣
            sortRecord.setUpdateTime(LocalDateTime.now());
            warehousingEntryDetailsSortMapper.updateById(sortRecord);
        }

        // 检查是否所有分拣都已完成，如果是，则更新明细记录状态为完成分拣(状态5)
        for (Long id : ids) {
            // 查询分拣记录
            WarehousingEntryDetailsSort sortRecord = warehousingEntryDetailsSortMapper.selectById(id);
            if (sortRecord != null) {
                // 查询该明细下的所有分拣记录
                LambdaQueryWrapper<WarehousingEntryDetailsSort> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(WarehousingEntryDetailsSort::getWarehousingEntryDetailsId,
                        sortRecord.getWarehousingEntryDetailsId());
                queryWrapper.eq(WarehousingEntryDetailsSort::getIsDel, 1);
                List<WarehousingEntryDetailsSort> sortRecords = warehousingEntryDetailsSortMapper.selectList(queryWrapper);

                // 检查是否所有分拣都已完成
                boolean allCompleted = sortRecords.stream()
                        .allMatch(record -> record.getStatus() == 2);

                if (allCompleted) {
                    // 更新明细记录状态为完成分拣(状态5)
                    WarehousingEntryDetails detail = new WarehousingEntryDetails();
                    detail.setId(sortRecord.getWarehousingEntryDetailsId());
                    detail.setStatus(5); // 完成分拣
                    detail.setUpdateTime(LocalDateTime.now());
                    warehousingEntryDetailsMapper.updateById(detail);
                }
            }
        }
    }

    @Override
    @Transactional
    public void revertSorting(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("请选择要撤销分拣状态的记录");
        }

        // 更新分拣记录状态为分拣中(状态1)
        for (Long id : ids) {
            WarehousingEntryDetailsSort sortRecord = new WarehousingEntryDetailsSort();
            sortRecord.setId(id);
            sortRecord.setStatus(1); // 分拣中
            sortRecord.setUpdateTime(LocalDateTime.now());
            warehousingEntryDetailsSortMapper.updateById(sortRecord);
        }

        // 检查是否有明细记录状态为完成分拣(状态5)，如果有则更新为已卸货(状态3)
        for (Long id : ids) {
            // 查询分拣记录
            WarehousingEntryDetailsSort sortRecord = warehousingEntryDetailsSortMapper.selectById(id);
            if (sortRecord != null) {
                // 查询明细记录
                WarehousingEntryDetails detail = warehousingEntryDetailsMapper.selectById(
                        sortRecord.getWarehousingEntryDetailsId());
                if (detail != null && detail.getStatus() == 5) {
                    // 更新明细记录状态为已卸货(状态3)
                    detail.setStatus(3); // 已卸货
                    detail.setUpdateTime(LocalDateTime.now());
                    warehousingEntryDetailsMapper.updateById(detail);
                }
            }
        }
    }

    @Override
    @Transactional
    public void performShelving(List<StockAsnController.ShelvingItem> items, List<Long> locationIds) {
        if (items == null || items.isEmpty()) {
            throw new RuntimeException("请选择要上架的商品");
        }

        if (locationIds == null || locationIds.isEmpty()) {
            throw new RuntimeException("请选择库位");
        }

        // 遍历上架商品列表
        for (StockAsnController.ShelvingItem item : items) {
            if (item.getId() == null) {
                throw new RuntimeException("商品ID不能为空");
            }

            if (item.getQuantity() == null || item.getQuantity() <= 0) {
                throw new RuntimeException("上架数量必须大于0");
            }

            // 查询分拣记录
            WarehousingEntryDetailsSort sortRecord = warehousingEntryDetailsSortMapper.selectById(item.getId());
            if (sortRecord == null) {
                throw new RuntimeException("未找到对应的分拣记录");
            }

            // 检查分拣记录状态是否为已完成分拣(状态2)
            if (sortRecord.getStatus() != 2) {
                throw new RuntimeException("只有已完成分拣的记录才能进行上架操作");
            }

            // 创建上架记录
            WarehousingEntryUp upRecord = new WarehousingEntryUp();
            upRecord.setSkuId(sortRecord.getSkuId());
            upRecord.setWarehouseId(1); // 需要根据实际业务确定仓库ID
            upRecord.setWarehouseAreaId(1); // 需要根据实际业务确定库区ID
            upRecord.setWarehouseAreaLocaId(1); // 需要根据实际业务确定库位ID
            upRecord.setCount(item.getQuantity());
            upRecord.setDetailsSortId(item.getId());
            upRecord.setStatus(1); // 未上架
            upRecord.setCreateTime(LocalDateTime.now());
            upRecord.setIsDel(1); // 未删除

            // 保存上架记录
            warehousingEntryUpMapper.insert(upRecord);

            // 更新分拣记录状态为已上架(状态3)
            sortRecord.setStatus(3); // 已上架
            sortRecord.setUpdateTime(LocalDateTime.now());
            warehousingEntryDetailsSortMapper.updateById(sortRecord);
        }
    }

    @Override
    @Transactional
    public void revertShelved(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("请选择要撤销上架状态的记录");
        }

        // 更新上架记录状态为未上架(状态1)
        for (Long id : ids) {
            WarehousingEntryUp upRecord = new WarehousingEntryUp();
            upRecord.setId(id);
            upRecord.setStatus(1); // 未上架
            upRecord.setUpdateTime(LocalDateTime.now());
            warehousingEntryUpMapper.updateById(upRecord);

            // 查询上架记录
            WarehousingEntryUp record = warehousingEntryUpMapper.selectById(id);
            if (record != null) {
                // 更新分拣记录状态为已完成分拣(状态2)
                WarehousingEntryDetailsSort sortRecord = new WarehousingEntryDetailsSort();
                sortRecord.setId(record.getDetailsSortId());
                sortRecord.setStatus(2); // 已完成分拣
                sortRecord.setUpdateTime(LocalDateTime.now());
                warehousingEntryDetailsSortMapper.updateById(sortRecord);
            }
        }
    }
}
